#include <sstream>
#include <map>
#include <nice2d/components/imagemanager.h>

namespace
{

std::string fn(const std::string &file,const sf::IntRect& area)
{
    std::stringstream stream;
    stream << file<<"\n"<<area.left<<","<<area.top<<","<<area.width<<","<<area.height;
    return stream.str();
};

}

class ImageManagerData
{
public:
    std::map<std::string,std::shared_ptr<sf::Image>> images;
    std::map<std::string,std::shared_ptr<sf::Texture>> textures;
};

ImageManager::ImageManager():
    data(new ImageManagerData())
{
}

ImageManager::~ImageManager()
{
}

void ImageManager::clear()
{
    data->images.clear();
    data->textures.clear();
}

std::shared_ptr<sf::Image> ImageManager::loadImageFromFile(const std::string &file)
{
    auto itr = data->images.find(file);
    if (itr != data->images.end())
        return itr->second;

    auto image = std::make_shared<sf::Image>();
    if (!image->loadFromFile(file))
        return nullptr;

    data->images.insert(std::make_pair(file,image));
    return image;
}

std::shared_ptr<sf::Texture> ImageManager::loadTextureFromFile(const std::string &file, const sf::IntRect &area)
{
    auto image = loadImageFromFile(file);
    if(!image)
        return nullptr;

    auto tag = fn(file,area);
    auto itr = data->textures.find(tag);
    if(itr == data->textures.end())
    {
        auto texture = std::make_shared<sf::Texture>();
        bool loaded = texture->loadFromImage(*image,area);
        if(!loaded)
            return nullptr;

        data->textures.insert({tag,texture});
        return texture;
    }
    else
        return itr->second;
}

PTree ImageManager::serialize()
{
    return PTree();
}

void ImageManager::deserialize(const PTree &node)
{

}
